package com.zhou.bjgl.bjgl.business_web.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhou.bjgl.bjgl.business_web.entity.wx.WxUser;
import com.zhou.bjgl.bjgl.business_web.mapper.WxUserMapper;
import com.zhou.bjgl.bjgl.constants.MqConstant;
import com.zhou.bjgl.bjgl.exception.BwException;
import com.zhou.bjgl.bjgl.exception.BwExceptionEnum;
import com.zhou.bjgl.bjgl.myAnnotations.UserLoginToken;
import com.zhou.bjgl.bjgl.req.BaseModel;
import com.zhou.bjgl.bjgl.req.user.UserEditPasswordReq;
import com.zhou.bjgl.bjgl.req.user.UserReq;
import com.zhou.bjgl.bjgl.resp.*;
import com.zhou.bjgl.bjgl.resp.common.ApiRestResponse;
import com.zhou.bjgl.bjgl.resp.router.BRouterResp;
import com.zhou.bjgl.bjgl.resp.user.BUserForInfoResp;
import com.zhou.bjgl.bjgl.resp.user.BUserForQueryResp;
import com.zhou.bjgl.bjgl.business_web.service.BMenuService;
import com.zhou.bjgl.bjgl.business_web.service.CommonService;
import com.zhou.bjgl.bjgl.business_web.service.TokenService;
import com.zhou.bjgl.bjgl.util.WechatUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * @ClassName: UserController
 * @Description: 公共管理模块
 * @Author: admin
 * @Date: 2021/7/4 14:35
 */
@RestController
@RequestMapping("/user")
@Api("公共管理")
//@CrossOrigin(allowCredentials="true")
public class CommonController extends BaseModel {
    @Resource
    private CommonService commonService;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Resource
    private TokenService tokenService;

    @Resource
    private BMenuService bMenuService;

    @Resource
    private WxUserMapper wxUserMapper;

    @ApiOperation("用户登录")
    @PostMapping("/login")
    public ApiRestResponse login(@RequestBody UserReq req, HttpServletRequest request) {

        HttpSession session = request.getSession();
        //判断登录信息进行登录
        BUserForQueryResp userResp = commonService.login(req);

        session.setAttribute("username", userResp.getUsername());
        session.setAttribute("collegeId", userResp.getCollegeId());
        session.setAttribute("classId", userResp.getClassId());
        session.setAttribute("id", userResp.getId());
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("roles", "admin");
        resultMap.put("power",userResp.getPower());
        resultMap.put("token", tokenService.getToken(req));
        return ApiRestResponse.success(resultMap);
    }


    @ApiOperation("微信账号密码登录(输入账号密码方式，后续改为微信登录）")
    @PostMapping("/wx-login")
    public ApiRestResponse wxLogin(@RequestBody UserReq req, HttpServletRequest request) {
        HttpSession session = request.getSession();
        BUserForQueryResp userResp = commonService.login(req);
        session.setAttribute("id", userResp.getId());
        session.setAttribute("collegeId", userResp.getCollegeId());
        session.setAttribute("classId", userResp.getClassId());
        session.setAttribute("token", tokenService.getToken(req));
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("userInfo", userResp);
        resultMap.put("token", tokenService.getToken(req));

        QueryWrapper<WxUser> wxUserQueryWrapper = new QueryWrapper<>();
        QueryWrapper<WxUser> user_id = wxUserQueryWrapper.eq("user_id", userResp.getId());
        WxUser wxUser = wxUserMapper.selectOne(user_id);
        if (wxUser!=null) {
            resultMap.put("alreadyBindWx", true);
        }
        return ApiRestResponse.success(resultMap);
    }


    @PostMapping("/wx/login")
    @ApiOperation("微信官方登录获取微信信息")
    public ApiRestResponse user_login(@RequestParam(value = "code", required = false) String code,
                                   @RequestParam(value = "rawData", required = false) String rawData,
                                   @RequestParam(value = "signature", required = false) String signature,
                                   @RequestParam(value = "encrypteData", required = false) String encrypteData,
                                   @RequestParam(value = "iv", required = false) String iv,
                                      @RequestParam(value = "userId", required = false) String userId) {
        // 用户非敏感信息：rawData
        // 签名：signature
        JSONObject rawDataJson = JSON.parseObject(rawData);
        // 1.接收小程序发送的code
        // 2.开发者服务器 登录凭证校验接口 appi + appsecret + code
        JSONObject SessionKeyOpenId = WechatUtil.getSessionKeyOrOpenId(code);
        // 3.接收微信接口服务 获取返回的参数
        String openid = SessionKeyOpenId.getString("openid");
        String sessionKey = SessionKeyOpenId.getString("session_key");

        // 4.校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
        String signature2 = DigestUtils.sha1Hex(rawData + sessionKey);
        if (!signature.equals(signature2)) {
            return ApiRestResponse.error(500, "签名校验失败");
        }
        // 5.根据返回的User实体类，判断用户是否是新用户，是的话，将用户信息存到数据库；不是的话，更新最新登录时间
        WxUser user = wxUserMapper.selectById(openid);

/*        //判断是否已经绑定
        if (user != null) {
            throw new BwException(BwExceptionEnum.ALLOW_ONE_USER);
        }*/

        if (user == null) {
            // 用户信息入库
            String nickName = rawDataJson.getString("nickName");
            String avatarUrl = rawDataJson.getString("avatarUrl");
            String gender = rawDataJson.getString("gender");
            String city = rawDataJson.getString("city");
            String country = rawDataJson.getString("country");
            String province = rawDataJson.getString("province");

            user = new WxUser();
            user.setOpenId(openid);
            user.setCreateTime(new Date());
            user.setLastVisitTime(new Date());
            user.setSessionKey(sessionKey);
            user.setCity(city);
            user.setProvince(province);
            user.setCountry(country);
            user.setAvatarUrl(avatarUrl);
            user.setGender(Integer.parseInt(gender));
            user.setNickName(nickName);
            user.setUserId(userId);

            wxUserMapper.insert(user);
        } else {
            // 已存在，更新用户登录时间
            user.setLastVisitTime(new Date());
            wxUserMapper.updateById(user);
        }
        //encrypteData比rowData多了appid和openid
        //JSONObject userInfo = WechatUtil.getUserInfo(encrypteData, sessionKey, iv);
        //6. 把新的skey返回给小程序
        return ApiRestResponse.success();
    }


    @PostMapping("/editPassword")
    @ApiOperation("修改密码")
    @UserLoginToken
    public ApiRestResponse editPassword(@RequestBody UserEditPasswordReq userEditPasswordReq) {
        try {
            commonService.changePassword(userEditPasswordReq);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BwException(BwExceptionEnum.EDIT_PASSWORD_FAIL);
        }
        UserReq userReq = new UserReq();
        userReq.setPassword(userEditPasswordReq.getNewPassword());
        userReq.setEmail(threadLocal.get().getEmail());
        //异步发送邮件
        rabbitTemplate.convertAndSend(MqConstant.MAIL_REGISTER_EXCHANGE, MqConstant.MAIL_REGISTER_ROUTING_KEY, userReq);
        return ApiRestResponse.success();
    }


    @GetMapping("/info")
    @ApiOperation("获取用户信息")
    @UserLoginToken
    public ApiRestResponse getInfo(HttpServletRequest request) {
        HttpSession session = request.getSession();
        BUserForInfoResp bUserForInfoResp = threadLocal.get();
        //获取路由表
        List<BRouterResp> routers = bMenuService.getRouterByUser(bUserForInfoResp.getPower());
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("user", "admin");
        resultMap.put("token", session.getAttribute("token"));
        resultMap.put("roles", "admin");
        resultMap.put("avatar", bUserForInfoResp.getProfileUrl());
        resultMap.put("routers", routers);
        resultMap.put("userInfo",bUserForInfoResp);
        return ApiRestResponse.success(resultMap);
    }


    @PostMapping("/logout")
    public ApiRestResponse logout(HttpSession session) {
        session.removeAttribute("user");
        session.removeAttribute("token");
        session.removeAttribute("roles");
        return ApiRestResponse.success();
    }


    @ApiOperation("获取班级列表")
    @GetMapping(value = {"/getClassData/", "/getClassData/{collegeId}"})
    @UserLoginToken
    public ApiRestResponse getClassData(@PathVariable(required = false) Long collegeId) {
        if (ObjectUtils.isEmpty(collegeId)) {
            return ApiRestResponse.success();
        }
        List<BClassResp> classData = commonService.getClassdata(collegeId);
        return ApiRestResponse.success(classData);
    }


    @ApiOperation("获取班级列表微信")
    @GetMapping(value = {"/getClassDataForWX/", "/getClassDataForWX/{collegeId}"})
    @UserLoginToken
    public ApiRestResponse getClassDataForWX(@PathVariable(required = false) Long collegeId) {
        if (ObjectUtils.isEmpty(collegeId)) {
            return ApiRestResponse.success();
        }
        List<BClassResp> classData = commonService.getClassdata(collegeId);

        //构造微信多级列表需要的数组对象

        ArrayList<WxListResp> wxListResps = new ArrayList<>(classData.size());

        for (BClassResp classDatum : classData) {
            WxListResp wxListResp = new WxListResp();
            wxListResp.setId(classDatum.getId());
            wxListResp.setText(classDatum.getClassName());
            wxListResps.add(wxListResp);
        }

        return ApiRestResponse.success(wxListResps);
    }

    @ApiOperation("获取学院列表")
    @GetMapping(value = {"/getCollegeData/", "/getCollegeData/{parentId}"})
    @UserLoginToken
    public ApiRestResponse getCollegeData(@PathVariable(required = false) Long parentId) {
        if (ObjectUtils.isEmpty(parentId)) {
            return ApiRestResponse.success();
        }
        List<BCollegeResp> CollegeData = commonService.getCollegedata(parentId);
        return ApiRestResponse.success(CollegeData);
    }

    @ApiOperation("获取学院列表微信")
    @GetMapping(value = {"/getCollegeDataForWX/", "/getCollegeDataForWX/{parentId}"})
    @UserLoginToken
    public ApiRestResponse getCollegeDataForWX(@PathVariable(required = false) Long parentId) {
        if (ObjectUtils.isEmpty(parentId)) {
            return ApiRestResponse.success();
        }
        List<BCollegeResp> bCollegeData = commonService.getCollegedata(parentId);

        //构造微信多级列表需要的数组对象
        List<WxListResp> wxListResps = new ArrayList<>(bCollegeData.size());

        for (BCollegeResp bCollegeDatum : bCollegeData) {
            WxListResp wxListResp = new WxListResp();
            wxListResp.setText(bCollegeDatum.getCollegeName());
            wxListResp.setId(bCollegeDatum.getId());
            wxListResps.add(wxListResp);
        }

        return ApiRestResponse.success(wxListResps);
    }

    @ApiOperation("获取权限列表")
    @GetMapping("/getRoleData")
    @UserLoginToken
    public ApiRestResponse getRoleData() {
        List<BRoleResp> roleData = commonService.getRoleData();
        return ApiRestResponse.success(roleData);
    }

    /**
     * 模拟注册，测试消息队列和邮件发送
     */
    @ApiOperation("邮件发送")
    @PostMapping("/register")
    public ApiRestResponse mockRegister(@RequestBody UserReq req) {

        // 邮件通知
        rabbitTemplate.convertAndSend(MqConstant.MAIL_REGISTER_EXCHANGE, MqConstant.MAIL_REGISTER_ROUTING_KEY, req);

        return ApiRestResponse.success("注册成功,注册信息将邮件通知");
    }

    @ApiOperation("修改头像")
    @PostMapping("/editHeadPortrait")
    @UserLoginToken
    public ApiRestResponse uploadHeadPortrait(@RequestParam(value = "profile") MultipartFile profile) {
        //调用上传头像方法进行上传
        String profileUrl = commonService.uploadProfile(profile);

        return ApiRestResponse.success(profileUrl);
    }

    @ApiOperation("修改用户信息")
    @PostMapping("/editInfo")
    @UserLoginToken
    public ApiRestResponse editUserInfo(@RequestBody UserReq userReq) {
        //调用service层进行信息修改
        try {
            commonService.changeUserInfo(userReq);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BwException(BwExceptionEnum.EDIT_PASSWORD_FAIL);
        }

        return ApiRestResponse.success("修改密码成功");
    }

}
